package com.xn2001.pattern;

import org.springframework.objenesis.instantiator.util.UnsafeUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;

/**
 * @author 乐心湖
 * @version 1.0
 * @date 2021/11/9 19:35
 */

public class TestSingleton {
    public static void main(String[] args) throws Exception {
        Singleton1.staticMethod();
        Singleton1.getInstance().method();
        System.out.println(Singleton1.getInstance());
        //反射调用私有构造破坏单例
        //reflection(Singleton1.class);

        //反序列化破坏单例
        //serializable(Singleton1.getInstance());

        //Unsafe破坏单例，无法预防
        unsafe(Singleton2.class);
    }

    public static void reflection(Class<?> clazz) throws Exception {
        Constructor<?> constructor = clazz.getDeclaredConstructor();
        constructor.setAccessible(true);
        System.out.println("反射创建实例，" + constructor.newInstance());
    }
    public static void serializable(Object instance) throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(instance);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
        System.out.println("反序列化创建实例，" + ois.readObject());
    }
    private static void unsafe(Class<?> clazz) throws Exception {
        Object o = UnsafeUtils.getUnsafe().allocateInstance(clazz);
        System.out.println("Unsafe创建实例，" + o);
    }
}
